﻿using Microsoft.Extensions.Caching.Distributed;
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Cms.Core.Infrastructure.Extension.Caching;
using Cms.Core.Infrastructure.Extension;
using Cms.Core.Application.Secutiry.Base;
using Cms.Core.Infrastructure.AuthHelper;
using Cms.Core.Application.Secutiry.Token;

namespace Cms.Core.Application.Secutiry
{
    /// <summary>
    /// 
    /// </summary>
    public class OnlineUserCache : OnlineCacheAbstract, IOnlineUserCache
    {


        private readonly IServiceProvider _serviceProvider;
        private readonly IDistributedCache _cache;
        private readonly PermissionRequirement _permissionRequirement;



        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceProvider"></param>
        public OnlineUserCache(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
            _cache = serviceProvider.GetService<IDistributedCache>();
            _permissionRequirement = serviceProvider.GetService<PermissionRequirement>();
        }






        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public OnlineUser GetOrRefresh(string userName)
        {
            userName.NotNullOrEmpty(nameof(userName));
            userName.NotNullOrEmpty(nameof(userName));

            string key = $"Cms_OnlineUser_{userName}";
            var options= base.SetSlidingExpiration(TimeSpan.FromMinutes(30));
            return _cache.Get<OnlineUser>(key, () =>
            {
                return _serviceProvider.ExecuteScopedWork<OnlineUser>(provider =>
                {
                    IOnlineUserProvider onlineUserProvider = provider.GetService<IOnlineUserProvider>();
                    return onlineUserProvider.Create(provider, userName).Result;

                });
            }, options);
            //string tokenKey = $"Cms_OnlineToken_{token}";
            //var  onlineToken= _cache.Get<OnlineToken>(tokenKey, () =>  //这里应该放在token中
            //{

            //    return _serviceProvider.ExecuteScopedWork<OnlineToken>(provider => {

            //        var permissionRequirement = provider.GetService<PermissionRequirement>();
            //        return new OnlineToken
            //        {
            //            ExpirationTime = exp,
            //            Token = token,
            //            RefreshTime = exp.AddMinutes(permissionRequirement.RefreshCoefficients),
            //        };
            //    });

            //}, options);
            //onlineUser.OnlineToken = onlineToken;

            //return onlineUser;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="token"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        public async Task<OnlineUser> GetOrRefreshAsync(string userName)
        {
           
            userName.NotNullOrEmpty(nameof(userName));
     
            string key = $"Cms_OnlineUser_{userName}";
            var options = base.SetSlidingExpiration(TimeSpan.FromMinutes(30));
            //DistributedCacheEntryOptions options = new DistributedCacheEntryOptions();
            //options.SetSlidingExpiration(TimeSpan.FromMinutes(30));
            return await _cache.GetAsync<OnlineUser>(key, () =>
            {
                return _serviceProvider.ExecuteScopedWorkAsync<OnlineUser>(async provider =>
                {
                    IOnlineUserProvider onlineUserProvider = provider.GetService<IOnlineUserProvider>();
                    return await onlineUserProvider.Create(provider, userName);

                });
            }, options);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userNames"></param>
        public void Remove(params string[] userNames)
        {

            foreach (var userName in userNames)
            {
                string key = $"Cms_OnlineUser_{userName}";
                _cache.Remove(key);
            }
        }
    }
}
